import { BadRequestException, Inject, Injectable } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import { ResultData } from '@/common/util/result';
import { GroupListDto } from './dto/chatroom-list.dto';
import * as dayjs from 'dayjs';

@Injectable()
export class ChatroomService {
    @Inject()
    private readonly prisma: PrismaService;
    async createOneToOneChatroom(userId: number, friendId: number) {
        const { id } = await this.prisma.chatroom.create({
            data: {
                name: '聊天室' + Math.random().toString().slice(2, 8),
                type: false
            },
            select: {
                id: true
            }
        });
        await this.prisma.userChatroom.create({
            data: {
                userId,
                chatroomId: id
            }
        })

        await this.prisma.userChatroom.create({
            data: {
                userId: friendId,
                chatroomId: id
            }
        })
        return ResultData.ok(id, '创建成功');
    }
    async createGroupChatroom(name: string, userId: number) {
        const { id } = await this.prisma.chatroom.create({
            data: {
                name,
                type: true
            },
            select: {
                id: true
            }
        });
        await this.prisma.userChatroom.create({
            data: {
                userId,
                chatroomId: id
            }
        })

        return ResultData.ok(null, '创建成功');
    }

    async list(userId: number, groupDto: GroupListDto) {
        const chatroomIds = await this.prisma.userChatroom.findMany({
            where: {
                userId
            },
            select: {
                chatroomId: true
            }
        })

        const chatrooms = await this.prisma.chatroom.findMany({
            where: {
                id: {
                    in: chatroomIds.map(item => item.chatroomId)
                },
                name: {
                    contains: groupDto.name
                }
            },
            select: {
                id: true,
                name: true,
                type: true,
                createTime: true
            },
            skip: (groupDto.page - 1) * groupDto.pageSize,
            take: groupDto.pageSize
        })

        const res = []
        for (let i = 0; i < chatrooms.length; i++) {
            let userIds = await this.prisma.userChatroom.findMany({
                where: {
                    chatroomId: chatrooms[i].id
                },
                select: {
                    userId: true
                }
            })

            chatrooms[i].createTime = dayjs(chatrooms[i].createTime).format('YYYY-MM-DD HH:mm:ss') as unknown as Date
            res.push({
                ...chatrooms[i],
                userCount: userIds.length,
                userIds: userIds.map(item => item.userId)
            })
        }
        return ResultData.ok({
            rows: res,
            total: await this.prisma.chatroom.count({
                where: {
                    id: {
                        in: chatroomIds.map(item => item.chatroomId)
                    },
                    name: {
                        contains: groupDto.name
                    }
                }
            })
        })
    }

    async allList(userId: number) {
        const chatroomIds = await this.prisma.userChatroom.findMany({
            where: {
                userId
            },
            select: {
                chatroomId: true
            }
        })

        const chatrooms = await this.prisma.chatroom.findMany({
            where: {
                id: {
                    in: chatroomIds.map(item => item.chatroomId)
                }
            },
            select: {
                id: true,
                name: true,
                type: true,
                createTime: true
            }
        })

        const res = []
        for (let i = 0; i < chatrooms.length; i++) {
            let userIds = await this.prisma.userChatroom.findMany({
                where: {
                    chatroomId: chatrooms[i].id
                },
                select: {
                    userId: true
                }
            })
            if (chatrooms[i].type === false) {
                const user = await this.prisma.user.findUnique({
                    where: {
                        id: userIds.filter(item => item.userId != userId)[0].userId
                    }
                })
                chatrooms[i].name = user.nickName
            }
            chatrooms[i].createTime = dayjs(chatrooms[i].createTime).format('YYYY-MM-DD HH:mm:ss') as unknown as Date
            res.push({
                ...chatrooms[i],
                userCount: userIds.length,
                userIds: userIds.map(item => item.userId)
            })
        }
        return ResultData.ok(res)
    }
    async chatroomDetail(userId: number, chatroomId: number) {

        const chatroom = await this.prisma.chatroom.findUnique({
            where: {
                id: chatroomId
            },
            select: {
                id: true,
                name: true,
                type: true,
                createTime: true
            }
        })

        let userIds = await this.prisma.userChatroom.findMany({
            where: {
                chatroomId: chatroom.id
            },
            select: {
                userId: true
            }
        })
        if (chatroom.type === false) {
            const user = await this.prisma.user.findUnique({
                where: {
                    id: userIds.filter(item => item.userId != userId)[0].userId
                }
            })
            chatroom.name = user.nickName
        }
        chatroom.createTime = dayjs(chatroom.createTime).format('YYYY-MM-DD HH:mm:ss') as unknown as Date
        return ResultData.ok({
            ...chatroom,
            userCount: userIds.length,
            userIds: userIds.map(item => item.userId)
        })
    }

    async members(chatroomId: number) {
        const userIds = await this.prisma.userChatroom.findMany({
            where: {
                chatroomId
            },
            select: {
                userId: true
            }
        })

        const users = await this.prisma.user.findMany({
            where: {
                id: {
                    in: userIds.map(item => item.userId)
                }
            },
            select: {
                id: true,
                username: true,
                nickName: true,
                headPic: true,
                createTime: true,
                email: true
            }
        })
        return ResultData.ok(users)
    }

    async info(id: number) {
        const chatroom = await this.prisma.chatroom.findUnique({
            where: {
                id
            }
        })
        return ResultData.ok({ ...chatroom, users: await this.members(id) })
    }

    async join(chatroomId: number, joinUserId: number) {
        const chatroom = await this.prisma.chatroom.findUnique({
            where: {
                id: chatroomId
            }
        })
        if (!chatroom) {
            return ResultData.fail(400, '聊天室不存在')
        }
        if (!chatroom.type) throw new BadRequestException('一对一聊天室不能加人');
        await this.prisma.userChatroom.create({
            data: {
                chatroomId,
                userId: joinUserId
            }
        })

        return ResultData.ok(null, '加入成功')
    }

    async quit(chatroomId: number, quitUserId: number) {
        const chatroom = await this.prisma.chatroom.findUnique({
            where: {
                id: chatroomId
            }
        })
        if (!chatroom) {
            return ResultData.fail(400, '聊天室不存在')
        }
        if (!chatroom.type) throw new BadRequestException('一对一聊天室不能退出');

        await this.prisma.userChatroom.delete({
            where: {
                userId_chatroomId: {
                    userId: quitUserId,
                    chatroomId: chatroomId
                }
            }
        })

        return ResultData.ok(null, '退出成功')
    }

    async queryOneToOneChatroom(userId1: number, userId2: number) {
        const chatrooms = await this.prisma.userChatroom.findMany({
            where: {
                userId: userId1
            }
        })
        const chatrooms2 = await this.prisma.userChatroom.findMany({
            where: {
                userId: userId2
            }
        })

        let res;
        for (let i = 0; i < chatrooms.length; i++) {
            const chatroom = await this.prisma.chatroom.findFirst({
                where: {
                    id: chatrooms[i].chatroomId
                }
            })
            if (chatroom.type === true) {
                continue;
            }

            const found = chatrooms2.find(item2 => item2.chatroomId === chatroom.id)
            if (found) {
                res = found.chatroomId
                break;
            }
        }

        return ResultData.ok(res)
    }
}
